library(ggplot2)
library(dplyr)
library(data.table)
library(plyr)
R_DATA_GENERAL <<- "/Users/luerlyu/Downloads/"
AVaxxerBefore <- read.csv(paste(R_DATA_GENERAL,"AVaxxer-before.csv",sep=""), quote="\"", header=T, comment.char="", sep=',')
AltRightBefore <- read.csv(paste(R_DATA_GENERAL,"Alt-right-before.csv",sep=""), quote="\"", header=T, comment.char="", sep=',')
AVaxxerAfter <- read.csv(paste(R_DATA_GENERAL,"AVaxxer-after.csv",sep=""), quote="\"", header=T, comment.char="", sep=',')
AltRightAfter <- read.csv(paste(R_DATA_GENERAL,"Alt-right-after.csv",sep=""), quote="\"", header=T, comment.char="", sep=',')
library(tidyverse)

AltRightAfter %>%
    mutate(sen = ifelse(str_detect(Message, "podcast"),
                          Message,
                          "")) %>%
    #select(sen)%>%
    filter(sen!="")
library(tidyverse)

AltRightAfter %>%
    mutate(sen = ifelse(str_detect(Message, "podcast"),
                          Message,
                          "")) %>%
    #select(sen)%>%
    filter(sen!="")%>%
    mutate(conservativeDaily = str_detect(Link, "ConservativeDaily")) %>%
    filter(conservativeDaily==T) %>%
    group_by(conservativeDaily)%>%
    summarise(Count= sum(conservativeDaily))
    #mutate(sen = factor(sen, levels = unique(sen)))
#418 out of 9328 entries are from conservative daily
AltRightAfter %>%
    mutate(sen = ifelse(str_detect(User.Name, "ConservativeDaily"),
                          User.Name,
                          "")) %>%
    #select(sen)%>%
    filter(sen!="")
AltRightBefore %>%
    mutate(sen = ifelse(str_detect(User.Name, "ConservativeDaily"),
                          User.Name,
                          "")) %>%
    #select(sen)%>%
    filter(sen!="")
AltRightBefore %>%
    mutate(sen = ifelse(str_detect(Message, "podcast"),
                          Message,
                          "")) %>%
    #select(sen)%>%
    filter(sen!="")

Word counts for each document

library(tidytext)
library(dplyr)
CleanAVaxxerBefore <- AVaxxerBefore %>%
    select(Message)%>%
    mutate(line = dplyr::row_number()) %>%
    unnest_tokens(word, Message) %>% #tokenize words
    anti_join(stop_words)
Joining, by = "word"
CleanAVaxxerBefore %>%
    count(word, sort = TRUE)
R_DATA_GENERAL <<- "/Users/luerlyu/Downloads/"
AVaxxerBefore_Clean <- read.csv(paste(R_DATA_GENERAL,"anti_before_cleaned.csv",sep=""), quote="\"", header=T, comment.char="", sep=',')
AltRightBefore_Clean <- read.csv(paste(R_DATA_GENERAL,"alt_before_cleaned.csv",sep=""), quote="\"", header=T, comment.char="", sep=',')
AVaxxerAfter_Clean <- read.csv(paste(R_DATA_GENERAL,"anti_after_cleaned.csv",sep=""), quote="\"", header=T, comment.char="", sep=',')
AltRightAfter_Clean <- read.csv(paste(R_DATA_GENERAL,"alt_after_cleaned.csv",sep=""), quote="\"", header=T, comment.char="", sep=',')
library(tidytext)
library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(stringr)

AVaxxerBefore_Clean <- AVaxxerBefore_Clean %>%
    select(Message)%>%
    mutate(line = dplyr::row_number()) %>%
    unnest_tokens(word, Message) %>% #tokenize words
    anti_join(stop_words)%>%
    filter(word!='vaccin')
Joining, by = "word"
AVaxxerBefore_Clean %>%
    count(word, sort = TRUE)
AVaxxerAfter_Clean <- AVaxxerAfter_Clean%>%
    select(Message)%>%
    mutate(line = dplyr::row_number()) %>%
    unnest_tokens(word, Message) %>% #tokenize words
    anti_join(stop_words)%>%
    filter(word!='vaccin')
Joining, by = "word"
AVaxxerAfter_Clean %>%
    count(word, sort = TRUE)
AltRightBefore_Clean <- AltRightBefore_Clean%>%
    select(Message)%>%
    mutate(line = dplyr::row_number()) %>%
    unnest_tokens(word, Message) %>% #tokenize words
    anti_join(stop_words)%>%
    filter(word!='vaccin')
Joining, by = "word"
AltRightBefore_Clean%>%
    count(word, sort = TRUE)
AltRightAfter_Clean <- AltRightAfter_Clean%>%
    select(Message)%>%
    mutate(line = dplyr::row_number()) %>%
    unnest_tokens(word, Message) %>% #tokenize words
    anti_join(stop_words)%>%
    filter(word!='vaccin')
Joining, by = "word"
AltRightAfter_Clean%>%
    count(word, sort = TRUE)
AltRightAfter_Clean <- AltRightAfter_Clean%>%
  mutate(category = "AltRightAfter")%>%
  select(c(word,category))

AltRightBefore_Clean <- AltRightBefore_Clean%>%
  mutate(category = "AltRightBefore")%>%
  select(c(word,category)) 

AVaxxerBefore_Clean <- AVaxxerBefore_Clean%>%
  mutate(category = "AVaxxerBefore")%>%
  select(c(word,category))

AVaxxerAfter_Clean <- AVaxxerAfter_Clean%>%
  mutate(category = "AVaxxerAfter")%>%
  select(c(word,category))
data <- bind_rows(AltRightAfter_Clean,AltRightBefore_Clean,AVaxxerBefore_Clean,AVaxxerAfter_Clean)
data

using STM to topic modeling

library(stm)

data_dfm <- data %>%
    count(category, word, sort = TRUE) %>%
    cast_dfm(category, word, n)

data_sparse <- data %>%
    count(category, word, sort = TRUE) %>%
    cast_sparse(category, word, n)

topic_model <- stm(AVaxxerBefore_dfm, K = 6, 
                   verbose = FALSE, init.type = "Spectral")
topic_model <- stm(data_dfm, K = 6, 
                   verbose = FALSE, init.type = "Spectral")
library(ggplot2)
Keep up to date with changes at https://www.tidyverse.org/blog/
td_beta <- tidy(topic_model)

td_beta %>%
    group_by(topic) %>%
    top_n(10, beta) %>%
    ungroup() %>%
    mutate(topic = paste0("Topic ", topic),
           term = reorder_within(term, beta, topic)) %>%
    ggplot(aes(term, beta, fill = as.factor(topic))) +
    geom_col(alpha = 0.8, show.legend = FALSE) +
    facet_wrap(~ topic, scales = "free_y") +
    coord_flip() +
    scale_x_reordered() +
    labs(x = NULL, y = expression(beta),
         title = "Highest word probabilities for each topic",
         subtitle = "Different words are associated with different topics")

td_gamma <- tidy(topic_model, matrix = "gamma",                    
                 document_names = rownames(data_dfm))

ggplot(td_gamma, aes(gamma, fill = as.factor(topic))) +
  geom_histogram(alpha = 0.8, show.legend = FALSE) +
  facet_wrap(~ topic, ncol = 3) +
  labs(title = "Distribution of document probabilities for each topic",
       subtitle = "Each topic is associated with 1 document",
       y = "Number of documents", x = expression(gamma))
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

td_gamma %>% 
  group_by(topic) %>% 
  mutate(possbility = max(gamma))%>%
  ungroup()%>%
  filter(possbility == gamma) %>%
  select(-c(gamma))

For topic 5 and 6, the possibility is lower than 0.25, which is quite unreliable topics to be assigned to the document, thus choosing less topics.

four topics

topic_model <- stm(data_dfm, K = 4, 
                   verbose = FALSE, init.type = "Spectral")
td_beta <- tidy(topic_model)

td_beta %>%
    group_by(topic) %>%
    top_n(10, beta) %>%
    ungroup() %>%
    mutate(topic = paste0("Topic ", topic),
           term = reorder_within(term, beta, topic)) %>%
    ggplot(aes(term, beta, fill = as.factor(topic))) +
    geom_col(alpha = 0.8, show.legend = FALSE) +
    facet_wrap(~ topic, scales = "free_y") +
    coord_flip() +
    scale_x_reordered() +
    labs(x = NULL, y = expression(beta),
         title = "Highest word probabilities for each topic",
         subtitle = "Different words are associated with different topics")

td_gamma <- tidy(topic_model, matrix = "gamma",                    
                 document_names = rownames(data_dfm))
td_gamma %>% 
  group_by(topic) %>% 
  mutate(possbility = max(gamma))%>%
  ungroup()%>%
  filter(possbility == gamma) %>%
  select(-c(gamma))
LS0tCnRpdGxlOiAiQ292aWRNaXNpbmZvIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGRhdGEudGFibGUpCmxpYnJhcnkocGx5cikKYGBgCgoKYGBge3J9ClJfREFUQV9HRU5FUkFMIDw8LSAiL1VzZXJzL2x1ZXJseXUvRG93bmxvYWRzLyIKQVZheHhlckJlZm9yZSA8LSByZWFkLmNzdihwYXN0ZShSX0RBVEFfR0VORVJBTCwiQVZheHhlci1iZWZvcmUuY3N2IixzZXA9IiIpLCBxdW90ZT0iXCIiLCBoZWFkZXI9VCwgY29tbWVudC5jaGFyPSIiLCBzZXA9JywnKQpBbHRSaWdodEJlZm9yZSA8LSByZWFkLmNzdihwYXN0ZShSX0RBVEFfR0VORVJBTCwiQWx0LXJpZ2h0LWJlZm9yZS5jc3YiLHNlcD0iIiksIHF1b3RlPSJcIiIsIGhlYWRlcj1ULCBjb21tZW50LmNoYXI9IiIsIHNlcD0nLCcpCkFWYXh4ZXJBZnRlciA8LSByZWFkLmNzdihwYXN0ZShSX0RBVEFfR0VORVJBTCwiQVZheHhlci1hZnRlci5jc3YiLHNlcD0iIiksIHF1b3RlPSJcIiIsIGhlYWRlcj1ULCBjb21tZW50LmNoYXI9IiIsIHNlcD0nLCcpCkFsdFJpZ2h0QWZ0ZXIgPC0gcmVhZC5jc3YocGFzdGUoUl9EQVRBX0dFTkVSQUwsIkFsdC1yaWdodC1hZnRlci5jc3YiLHNlcD0iIiksIHF1b3RlPSJcIiIsIGhlYWRlcj1ULCBjb21tZW50LmNoYXI9IiIsIHNlcD0nLCcpCmBgYAoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQoKQWx0UmlnaHRBZnRlciAlPiUKICAgIG11dGF0ZShzZW4gPSBpZmVsc2Uoc3RyX2RldGVjdChNZXNzYWdlLCAicG9kY2FzdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIiIpKSAlPiUKICAgICNzZWxlY3Qoc2VuKSU+JQogICAgZmlsdGVyKHNlbiE9IiIpCmBgYAoKCmBgYHtyfQoKQWx0UmlnaHRBZnRlciAlPiUKICAgIG11dGF0ZShzZW4gPSBpZmVsc2Uoc3RyX2RldGVjdChNZXNzYWdlLCAicG9kY2FzdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIiIpKSAlPiUKICAgICNzZWxlY3Qoc2VuKSU+JQogICAgZmlsdGVyKHNlbiE9IiIpJT4lCiAgICBtdXRhdGUoY29uc2VydmF0aXZlRGFpbHkgPSBzdHJfZGV0ZWN0KExpbmssICJDb25zZXJ2YXRpdmVEYWlseSIpKSAlPiUKICAgIGZpbHRlcihjb25zZXJ2YXRpdmVEYWlseT09VCkgJT4lCiAgICBncm91cF9ieShjb25zZXJ2YXRpdmVEYWlseSklPiUKICAgIHN1bW1hcmlzZShDb3VudD0gc3VtKGNvbnNlcnZhdGl2ZURhaWx5KSkKICAgICNtdXRhdGUoc2VuID0gZmFjdG9yKHNlbiwgbGV2ZWxzID0gdW5pcXVlKHNlbikpKQpgYGAKYGBge3J9CiM0MTggb3V0IG9mIDkzMjggZW50cmllcyBhcmUgZnJvbSBjb25zZXJ2YXRpdmUgZGFpbHkKQWx0UmlnaHRBZnRlciAlPiUKICAgIG11dGF0ZShzZW4gPSBpZmVsc2Uoc3RyX2RldGVjdChVc2VyLk5hbWUsICJDb25zZXJ2YXRpdmVEYWlseSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVzZXIuTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAiIikpICU+JQogICAgI3NlbGVjdChzZW4pJT4lCiAgICBmaWx0ZXIoc2VuIT0iIikKYGBgCgpgYGB7cn0KQWx0UmlnaHRCZWZvcmUgJT4lCiAgICBtdXRhdGUoc2VuID0gaWZlbHNlKHN0cl9kZXRlY3QoVXNlci5OYW1lLCAiQ29uc2VydmF0aXZlRGFpbHkiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBVc2VyLk5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIiIpKSAlPiUKICAgICNzZWxlY3Qoc2VuKSU+JQogICAgZmlsdGVyKHNlbiE9IiIpCmBgYAoKYGBge3J9CkFsdFJpZ2h0QmVmb3JlICU+JQogICAgbXV0YXRlKHNlbiA9IGlmZWxzZShzdHJfZGV0ZWN0KE1lc3NhZ2UsICJwb2RjYXN0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAiIikpICU+JQogICAgI3NlbGVjdChzZW4pJT4lCiAgICBmaWx0ZXIoc2VuIT0iIikKYGBgCgojIyBXb3JkIGNvdW50cyBmb3IgZWFjaCBkb2N1bWVudApgYGB7cn0KbGlicmFyeSh0aWR5dGV4dCkKbGlicmFyeShkcGx5cikKbGlicmFyeShzdHJpbmdyKQoKQVZheHhlckJlZm9yZSAlPiUKICAgIHNlbGVjdChNZXNzYWdlKSU+JQogICAgbXV0YXRlKGxpbmUgPSBkcGx5cjo6cm93X251bWJlcigpKSAlPiUKICAgIHVubmVzdF90b2tlbnMod29yZCwgTWVzc2FnZSkgJT4lICN0b2tlbml6ZSB3b3JkcwogICAgYW50aV9qb2luKHN0b3Bfd29yZHMpJT4lCiAgICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkKYGBgCgpgYGB7cn0KUl9EQVRBX0dFTkVSQUwgPDwtICIvVXNlcnMvbHVlcmx5dS9Eb3dubG9hZHMvIgpBVmF4eGVyQmVmb3JlX0NsZWFuIDwtIHJlYWQuY3N2KHBhc3RlKFJfREFUQV9HRU5FUkFMLCJhbnRpX2JlZm9yZV9jbGVhbmVkLmNzdiIsc2VwPSIiKSwgcXVvdGU9IlwiIiwgaGVhZGVyPVQsIGNvbW1lbnQuY2hhcj0iIiwgc2VwPScsJykKQWx0UmlnaHRCZWZvcmVfQ2xlYW4gPC0gcmVhZC5jc3YocGFzdGUoUl9EQVRBX0dFTkVSQUwsImFsdF9iZWZvcmVfY2xlYW5lZC5jc3YiLHNlcD0iIiksIHF1b3RlPSJcIiIsIGhlYWRlcj1ULCBjb21tZW50LmNoYXI9IiIsIHNlcD0nLCcpCkFWYXh4ZXJBZnRlcl9DbGVhbiA8LSByZWFkLmNzdihwYXN0ZShSX0RBVEFfR0VORVJBTCwiYW50aV9hZnRlcl9jbGVhbmVkLmNzdiIsc2VwPSIiKSwgcXVvdGU9IlwiIiwgaGVhZGVyPVQsIGNvbW1lbnQuY2hhcj0iIiwgc2VwPScsJykKQWx0UmlnaHRBZnRlcl9DbGVhbiA8LSByZWFkLmNzdihwYXN0ZShSX0RBVEFfR0VORVJBTCwiYWx0X2FmdGVyX2NsZWFuZWQuY3N2IixzZXA9IiIpLCBxdW90ZT0iXCIiLCBoZWFkZXI9VCwgY29tbWVudC5jaGFyPSIiLCBzZXA9JywnKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KHRpZHl0ZXh0KQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHN0cmluZ3IpCgpBVmF4eGVyQmVmb3JlX0NsZWFuIDwtIEFWYXh4ZXJCZWZvcmVfQ2xlYW4gJT4lCiAgICBzZWxlY3QoTWVzc2FnZSklPiUKICAgIG11dGF0ZShsaW5lID0gZHBseXI6OnJvd19udW1iZXIoKSkgJT4lCiAgICB1bm5lc3RfdG9rZW5zKHdvcmQsIE1lc3NhZ2UpICU+JSAjdG9rZW5pemUgd29yZHMKICAgIGFudGlfam9pbihzdG9wX3dvcmRzKSU+JQogICAgZmlsdGVyKHdvcmQhPSd2YWNjaW4nKQpBVmF4eGVyQmVmb3JlX0NsZWFuICU+JQogICAgY291bnQod29yZCwgc29ydCA9IFRSVUUpCmBgYAoKCmBgYHtyfQpBVmF4eGVyQWZ0ZXJfQ2xlYW4gPC0gQVZheHhlckFmdGVyX0NsZWFuJT4lCiAgICBzZWxlY3QoTWVzc2FnZSklPiUKICAgIG11dGF0ZShsaW5lID0gZHBseXI6OnJvd19udW1iZXIoKSkgJT4lCiAgICB1bm5lc3RfdG9rZW5zKHdvcmQsIE1lc3NhZ2UpICU+JSAjdG9rZW5pemUgd29yZHMKICAgIGFudGlfam9pbihzdG9wX3dvcmRzKSU+JQogICAgZmlsdGVyKHdvcmQhPSd2YWNjaW4nKQpBVmF4eGVyQWZ0ZXJfQ2xlYW4gJT4lCiAgICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkKYGBgCgpgYGB7cn0KQWx0UmlnaHRCZWZvcmVfQ2xlYW4gPC0gQWx0UmlnaHRCZWZvcmVfQ2xlYW4lPiUKICAgIHNlbGVjdChNZXNzYWdlKSU+JQogICAgbXV0YXRlKGxpbmUgPSBkcGx5cjo6cm93X251bWJlcigpKSAlPiUKICAgIHVubmVzdF90b2tlbnMod29yZCwgTWVzc2FnZSkgJT4lICN0b2tlbml6ZSB3b3JkcwogICAgYW50aV9qb2luKHN0b3Bfd29yZHMpJT4lCiAgICBmaWx0ZXIod29yZCE9J3ZhY2NpbicpCkFsdFJpZ2h0QmVmb3JlX0NsZWFuJT4lCiAgICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkKYGBgCgpgYGB7cn0KQWx0UmlnaHRBZnRlcl9DbGVhbiA8LSBBbHRSaWdodEFmdGVyX0NsZWFuJT4lCiAgICBzZWxlY3QoTWVzc2FnZSklPiUKICAgIG11dGF0ZShsaW5lID0gZHBseXI6OnJvd19udW1iZXIoKSkgJT4lCiAgICB1bm5lc3RfdG9rZW5zKHdvcmQsIE1lc3NhZ2UpICU+JSAjdG9rZW5pemUgd29yZHMKICAgIGFudGlfam9pbihzdG9wX3dvcmRzKSU+JQogICAgZmlsdGVyKHdvcmQhPSd2YWNjaW4nKQpBbHRSaWdodEFmdGVyX0NsZWFuJT4lCiAgICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkKYGBgCgpgYGB7cn0KQWx0UmlnaHRBZnRlcl9DbGVhbiA8LSBBbHRSaWdodEFmdGVyX0NsZWFuJT4lCiAgbXV0YXRlKGNhdGVnb3J5ID0gIkFsdFJpZ2h0QWZ0ZXIiKSU+JQogIHNlbGVjdChjKHdvcmQsY2F0ZWdvcnkpKQoKQWx0UmlnaHRCZWZvcmVfQ2xlYW4gPC0gQWx0UmlnaHRCZWZvcmVfQ2xlYW4lPiUKICBtdXRhdGUoY2F0ZWdvcnkgPSAiQWx0UmlnaHRCZWZvcmUiKSU+JQogIHNlbGVjdChjKHdvcmQsY2F0ZWdvcnkpKSAKCkFWYXh4ZXJCZWZvcmVfQ2xlYW4gPC0gQVZheHhlckJlZm9yZV9DbGVhbiU+JQogIG11dGF0ZShjYXRlZ29yeSA9ICJBVmF4eGVyQmVmb3JlIiklPiUKICBzZWxlY3QoYyh3b3JkLGNhdGVnb3J5KSkKCkFWYXh4ZXJBZnRlcl9DbGVhbiA8LSBBVmF4eGVyQWZ0ZXJfQ2xlYW4lPiUKICBtdXRhdGUoY2F0ZWdvcnkgPSAiQVZheHhlckFmdGVyIiklPiUKICBzZWxlY3QoYyh3b3JkLGNhdGVnb3J5KSkKCmBgYAoKYGBge3J9CmRhdGEgPC0gYmluZF9yb3dzKEFsdFJpZ2h0QWZ0ZXJfQ2xlYW4sQWx0UmlnaHRCZWZvcmVfQ2xlYW4sQVZheHhlckJlZm9yZV9DbGVhbixBVmF4eGVyQWZ0ZXJfQ2xlYW4pCmRhdGEKYGBgCiMjIHVzaW5nIFNUTSB0byB0b3BpYyBtb2RlbGluZwoKYGBge3J9CmxpYnJhcnkoc3RtKQoKZGF0YV9kZm0gPC0gZGF0YSAlPiUKICAgIGNvdW50KGNhdGVnb3J5LCB3b3JkLCBzb3J0ID0gVFJVRSkgJT4lCiAgICBjYXN0X2RmbShjYXRlZ29yeSwgd29yZCwgbikKCmRhdGFfc3BhcnNlIDwtIGRhdGEgJT4lCiAgICBjb3VudChjYXRlZ29yeSwgd29yZCwgc29ydCA9IFRSVUUpICU+JQogICAgY2FzdF9zcGFyc2UoY2F0ZWdvcnksIHdvcmQsIG4pCgpgYGAKCmBgYHtyfQp0b3BpY19tb2RlbCA8LSBzdG0oZGF0YV9kZm0sIEsgPSA2LCAKICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSwgaW5pdC50eXBlID0gIlNwZWN0cmFsIikKYGBgCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQp0ZF9iZXRhIDwtIHRpZHkodG9waWNfbW9kZWwpCgp0ZF9iZXRhICU+JQogICAgZ3JvdXBfYnkodG9waWMpICU+JQogICAgdG9wX24oMTAsIGJldGEpICU+JQogICAgdW5ncm91cCgpICU+JQogICAgbXV0YXRlKHRvcGljID0gcGFzdGUwKCJUb3BpYyAiLCB0b3BpYyksCiAgICAgICAgICAgdGVybSA9IHJlb3JkZXJfd2l0aGluKHRlcm0sIGJldGEsIHRvcGljKSkgJT4lCiAgICBnZ3Bsb3QoYWVzKHRlcm0sIGJldGEsIGZpbGwgPSBhcy5mYWN0b3IodG9waWMpKSkgKwogICAgZ2VvbV9jb2woYWxwaGEgPSAwLjgsIHNob3cubGVnZW5kID0gRkFMU0UpICsKICAgIGZhY2V0X3dyYXAofiB0b3BpYywgc2NhbGVzID0gImZyZWVfeSIpICsKICAgIGNvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV94X3Jlb3JkZXJlZCgpICsKICAgIGxhYnMoeCA9IE5VTEwsIHkgPSBleHByZXNzaW9uKGJldGEpLAogICAgICAgICB0aXRsZSA9ICJIaWdoZXN0IHdvcmQgcHJvYmFiaWxpdGllcyBmb3IgZWFjaCB0b3BpYyIsCiAgICAgICAgIHN1YnRpdGxlID0gIkRpZmZlcmVudCB3b3JkcyBhcmUgYXNzb2NpYXRlZCB3aXRoIGRpZmZlcmVudCB0b3BpY3MiKQpgYGAKCgpgYGB7cn0KdGRfZ2FtbWEgPC0gdGlkeSh0b3BpY19tb2RlbCwgbWF0cml4ID0gImdhbW1hIiwgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgIGRvY3VtZW50X25hbWVzID0gcm93bmFtZXMoZGF0YV9kZm0pKQoKZ2dwbG90KHRkX2dhbW1hLCBhZXMoZ2FtbWEsIGZpbGwgPSBhcy5mYWN0b3IodG9waWMpKSkgKwogIGdlb21faGlzdG9ncmFtKGFscGhhID0gMC44LCBzaG93LmxlZ2VuZCA9IEZBTFNFKSArCiAgZmFjZXRfd3JhcCh+IHRvcGljLCBuY29sID0gMykgKwogIGxhYnModGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIGRvY3VtZW50IHByb2JhYmlsaXRpZXMgZm9yIGVhY2ggdG9waWMiLAogICAgICAgc3VidGl0bGUgPSAiRWFjaCB0b3BpYyBpcyBhc3NvY2lhdGVkIHdpdGggMSBkb2N1bWVudCIsCiAgICAgICB5ID0gIk51bWJlciBvZiBkb2N1bWVudHMiLCB4ID0gZXhwcmVzc2lvbihnYW1tYSkpCmBgYApgYGB7cn0KdGRfZ2FtbWEgJT4lIAogIGdyb3VwX2J5KHRvcGljKSAlPiUgCiAgbXV0YXRlKHBvc3NiaWxpdHkgPSBtYXgoZ2FtbWEpKSU+JQogIHVuZ3JvdXAoKSU+JQogIGZpbHRlcihwb3NzYmlsaXR5ID09IGdhbW1hKSAlPiUKICBzZWxlY3QoLWMoZ2FtbWEpKQpgYGAKRm9yIHRvcGljIDUgYW5kIDYsIHRoZSBwb3NzaWJpbGl0eSBpcyBsb3dlciB0aGFuIDAuMjUsIHdoaWNoIGlzIHF1aXRlIHVucmVsaWFibGUgdG9waWNzIHRvIGJlIGFzc2lnbmVkIHRvIHRoZSBkb2N1bWVudCwgdGh1cyBjaG9vc2luZyBsZXNzIHRvcGljcy4KCiMjIyBmb3VyIHRvcGljcwpgYGB7cn0KdG9waWNfbW9kZWwgPC0gc3RtKGRhdGFfZGZtLCBLID0gNCwgCiAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsIGluaXQudHlwZSA9ICJTcGVjdHJhbCIpCnRkX2JldGEgPC0gdGlkeSh0b3BpY19tb2RlbCkKCnRkX2JldGEgJT4lCiAgICBncm91cF9ieSh0b3BpYykgJT4lCiAgICB0b3BfbigxMCwgYmV0YSkgJT4lCiAgICB1bmdyb3VwKCkgJT4lCiAgICBtdXRhdGUodG9waWMgPSBwYXN0ZTAoIlRvcGljICIsIHRvcGljKSwKICAgICAgICAgICB0ZXJtID0gcmVvcmRlcl93aXRoaW4odGVybSwgYmV0YSwgdG9waWMpKSAlPiUKICAgIGdncGxvdChhZXModGVybSwgYmV0YSwgZmlsbCA9IGFzLmZhY3Rvcih0b3BpYykpKSArCiAgICBnZW9tX2NvbChhbHBoYSA9IDAuOCwgc2hvdy5sZWdlbmQgPSBGQUxTRSkgKwogICAgZmFjZXRfd3JhcCh+IHRvcGljLCBzY2FsZXMgPSAiZnJlZV95IikgKwogICAgY29vcmRfZmxpcCgpICsKICAgIHNjYWxlX3hfcmVvcmRlcmVkKCkgKwogICAgbGFicyh4ID0gTlVMTCwgeSA9IGV4cHJlc3Npb24oYmV0YSksCiAgICAgICAgIHRpdGxlID0gIkhpZ2hlc3Qgd29yZCBwcm9iYWJpbGl0aWVzIGZvciBlYWNoIHRvcGljIiwKICAgICAgICAgc3VidGl0bGUgPSAiRGlmZmVyZW50IHdvcmRzIGFyZSBhc3NvY2lhdGVkIHdpdGggZGlmZmVyZW50IHRvcGljcyIpCmBgYAoKYGBge3J9CnRkX2dhbW1hIDwtIHRpZHkodG9waWNfbW9kZWwsIG1hdHJpeCA9ICJnYW1tYSIsICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICBkb2N1bWVudF9uYW1lcyA9IHJvd25hbWVzKGRhdGFfZGZtKSkKdGRfZ2FtbWEgJT4lIAogIGdyb3VwX2J5KHRvcGljKSAlPiUgCiAgbXV0YXRlKHBvc3NiaWxpdHkgPSBtYXgoZ2FtbWEpKSU+JQogIHVuZ3JvdXAoKSU+JQogIGZpbHRlcihwb3NzYmlsaXR5ID09IGdhbW1hKSAlPiUKICBzZWxlY3QoLWMoZ2FtbWEpKQpgYGAK